﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.Creation;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.DataModel;
using YArchitech.LIB;
using YArchitech.MEP;
using YArchitech.Revit;

namespace YArchitech.HVAC
{
	[Transaction(TransactionMode.Manual)]
	[Regeneration(RegenerationOption.Manual)]
	public class LayEquipment : IExternalCommand
	{
		public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			Transaction transaction = null;
			Result result;
			try
			{
				if (commandData == null)
				{
					throw new System.ArgumentNullException();
				}
				UIApplication application = commandData.Application;
				UIDocument activeUIDocument = application.ActiveUIDocument;
				Document document = activeUIDocument.Document;
				Selection selection = activeUIDocument.Selection;
				if (!YJKRevitTools.ViewCheck(activeUIDocument, new List<ViewType>
				{
					1,
					2,
					4
				}))
				{
					result = Autodesk.Revit.UI.Result.Cancelled;
				}
				else
				{
					List<Family> listDuctFan;
					List<Family> listOtherFan;
					LayEquipment.GroupingFans(out transaction, document, out listDuctFan, out listOtherFan);
					for (;;)
					{
						if (transaction != null && (int)transaction.GetStatus() == 1)
						{
							transaction.Commit();
						}
						HYEquipmentCommon hyequipmentCommon = new HYEquipmentCommon();
						ICollection<ElementId> allFamilyInstance = hyequipmentCommon.GetAllFamilyInstance(document, BuiltInCategory.OST_MechanicalEquipment);
						SpaceFamilyDataReader spaceFamilyDataReader = new SpaceFamilyDataReader();
						FormLayFan formLayFan = new FormLayFan(document, listDuctFan, listOtherFan);
						DialogResult dialogResult = formLayFan.ShowDialog();
						if (dialogResult == DialogResult.OK)
						{
							EquipmentFanParam2 fanParam = formLayFan.fanParam;
							FamilySymbol familySymbol = formLayFan.fs;
							if (familySymbol == null)
							{
								familySymbol = spaceFamilyDataReader.GetFamilySymbolById(fanParam.Id, "Fan", fanParam.SymbolName, document, BuiltInCategory.OST_MechanicalEquipment);
							}
							if (formLayFan.bLayDuct)
							{
								if (!this.LayFansinDuct(familySymbol, document, selection, fanParam, formLayFan.bLayFlex, formLayFan.hongye))
								{
									break;
								}
							}
							else if (familySymbol != null)
							{
								try
								{
									activeUIDocument.PromptForFamilyInstancePlacement(familySymbol);
								}
								catch (Autodesk.Revit.Exceptions.OperationCanceledException)
								{
								}
							}
							ICollection<ElementId> allFamilyInstance2 = hyequipmentCommon.GetAllFamilyInstance(document, BuiltInCategory.OST_MechanicalEquipment);
							new List<ElementId>();
							foreach (ElementId item in allFamilyInstance.Intersect(allFamilyInstance2))
							{
								allFamilyInstance2.Remove(item);
							}
							transaction = new Transaction(document, "设置风机的参数");
							transaction.Start();
							IEnumerator<ElementId> enumerator = allFamilyInstance2.GetEnumerator();
							{
								while (enumerator.MoveNext())
								{
									ElementId elementId = enumerator.Current;
									Element elementById = document.GetElementById(elementId);
									HYParametersSetting hyparametersSetting = new HYParametersSetting(application);
									Parameter parameter = elementById.GetParameter("统计名称");
									if (parameter == null)
									{
										hyparametersSetting.SetFanShareParam();
										parameter = elementById.GetParameter("统计名称");
									}
									if (parameter != null)
									{
										parameter.Set(fanParam.FamilyName);
									}
									document.Regenerate();
									if (!formLayFan.bLayDuct && formLayFan.hongye)
									{
										if (fanParam.FamilyName == "离心式管道风机")
										{
											Parameter parameter2 = elementById.GetParameter("风机长度");
											if (parameter2 != null && !parameter2.IsReadOnly)
											{
												parameter2.Set(NumbericTools.mmToFeet(fanParam.Length));
											}
											Parameter parameter3 = elementById.GetParameter("入口宽度");
											if (parameter3 != null && !parameter3.IsReadOnly)
											{
												parameter3.Set(NumbericTools.mmToFeet(fanParam.Width));
											}
											Parameter parameter4 = elementById.GetParameter("入口高度");
											if (parameter4 != null && !parameter4.IsReadOnly)
											{
												parameter4.Set(NumbericTools.mmToFeet(fanParam.Height));
											}
										}
										else if (fanParam.FamilyName == "轴流式管道风机")
										{
											Parameter parameter5 = elementById.GetParameter("风机长度");
											if (parameter5 != null && !parameter5.IsReadOnly)
											{
												parameter5.Set(NumbericTools.mmToFeet(fanParam.Length));
											}
											Parameter parameter6 = elementById.GetParameter("入口直径");
											if (parameter6 != null && !parameter6.IsReadOnly)
											{
												parameter6.Set(NumbericTools.mmToFeet(fanParam.Diameter));
											}
										}
										else if (fanParam.FamilyName == "方形轴流风机")
										{
											Parameter parameter7 = elementById.GetParameter("风机长度");
											if (parameter7 != null && !parameter7.IsReadOnly)
											{
												parameter7.Set(NumbericTools.mmToFeet(fanParam.Length));
											}
											Parameter parameter8 = elementById.GetParameter("风机宽度");
											if (parameter8 != null && !parameter8.IsReadOnly)
											{
												parameter8.Set(NumbericTools.mmToFeet(fanParam.Width));
											}
										}
										else if (fanParam.FamilyName == "屋顶风机-离心式" || fanParam.FamilyName == "屋顶风机-轴流式")
										{
											Parameter parameter9 = elementById.GetParameter("风机直径");
											if (parameter9 != null && !parameter9.IsReadOnly)
											{
												parameter9.Set(NumbericTools.mmToFeet(fanParam.Diameter));
											}
										}
									}
									if (!formLayFan.bLayDuct)
									{
										Parameter parameter10 = null;
										Parameter parameter11 = null;
										double num = 0.0;
										if (elementById.GetParameter(BuiltInParameter.INSTANCE_ELEVATION_PARAM) != null)
										{
											parameter11 = elementById.GetParameter(BuiltInParameter.INSTANCE_ELEVATION_PARAM);
										}
										else
										{
											Parameter parameter12 = elementById.GetParameter(BuiltInParameter.FAMILY_LEVEL_PARAM);
											if (parameter12 != null)
											{
												parameter12.Set(document.ActiveView.GenLevel.Id);
											}
										}
										if (parameter11 != null)
										{
											parameter11.Set(UnitConvert.CovertToAPI(fanParam.OffSet * 1000.0, (Autodesk.Revit.DB.DisplayUnitType)2));
											num = parameter11.AsDouble();
										}
										if (num != UnitConvert.CovertToAPI(fanParam.OffSet * 1000.0, (Autodesk.Revit.DB.DisplayUnitType)2))
										{
											if (elementById.GetParameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM) != null)
											{
												parameter10 = elementById.GetParameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM);
											}
											if (parameter10 != null)
											{
												parameter10.Set(UnitConvert.CovertToAPI(fanParam.OffSet * 1000.0, (Autodesk.Revit.DB.DisplayUnitType)2));
											}
										}
										document.Regenerate();
									}
								}
								continue;
							}
						}
						if (dialogResult == DialogResult.Cancel)
						{
							goto Block_15;
						}
					}
					return Autodesk.Revit.UI.Result.Cancelled;
					Block_15:
					result = Autodesk.Revit.UI.Result.Succeeded;
				}
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Exception ex)
			{
				message = ex.Message;
				result = Autodesk.Revit.UI.Result.Failed;
			}
			finally
			{
				if (transaction != null)
				{
					if ((int)transaction.GetStatus() == 1)
					{
						transaction.Commit();
					}
					if ((int)transaction.GetStatus() != 3 && (int)transaction.GetStatus() != 2)
					{
						transaction.RollBack();
					}
				}
			}
			return result;
		}

		private static void GroupingFans(out Transaction tran1, Autodesk.Revit.DB.Document doc, out List<Family> listDuctFan, out List<Family> listOtherFan)
		{
			List<Family> list = HyProjectFamily.GetFamilys(BuiltInCategory.OST_MechanicalEquipment, doc).FindAll((Family p) => (p.Name.Contains("风机") || p.Name.Contains("FAN") || p.Name.Contains("fan")) && !p.Name.Contains("风机盘管")).ToList<Family>();
			listDuctFan = new List<Family>();
			listOtherFan = new List<Family>();
			tran1 = new Transaction(doc, "过滤当前项目族类型");
			tran1.Start();
			foreach (Family family in list)
			{
				List<FamilySymbol> symbols = family.GetSymbols();
				if (symbols.Count > 0)
				{
					FamilySymbol familySymbol = symbols.ElementAt(0);
					familySymbol.Activate();
					FamilyInstance familyInstance = doc.Create.NewFamilyInstance(new XYZ(), familySymbol, (Autodesk.Revit.DB.Structure.StructuralType)0);
					doc.Regenerate();
					if (familyInstance != null)
					{
						int num = 0;
						MEPModel mepmodel = familyInstance.MEPModel;
						if (mepmodel == null)
						{
							doc.DeleteElement(familyInstance);
						}
						else
						{
							ConnectorManager connectorManager = mepmodel.ConnectorManager;
							if (connectorManager == null)
							{
								doc.DeleteElement(familyInstance);
							}
							else
							{
								ConnectorSetIterator connectorSetIterator = connectorManager.Connectors.ForwardIterator();
								while (connectorSetIterator.MoveNext())
								{
									if ((connectorSetIterator.Current as Connector).Domain == (Autodesk.Revit.DB.Domain)1)
									{
										num++;
									}
								}
								if (num > 1)
								{
									listDuctFan.Add(family);
								}
								else if (num > 0)
								{
									listOtherFan.Add(family);
								}
								else if (num == 0 && familyInstance.MEPModel.ConnectorManager.Connectors.Size == 1)
								{
									listOtherFan.Add(family);
								}
								doc.DeleteElement(familyInstance);
							}
						}
					}
				}
			}
			tran1.Commit();
		}

		private bool LayFansinDuct(FamilySymbol fs, Autodesk.Revit.DB.Document doc, Selection sel, EquipmentFanParam2 fanParam, bool bLayFlex, bool hongye)
		{
			bool result = false;
			ConnectHelper connectHelper = new ConnectHelper();
			Transaction transaction = new Transaction(doc, "附加风机");
			try
			{
				transaction.Start();
				for (;;)
				{
					Reference reference = sel.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, new DuctFilter(), "请选择要放置风机的风管：");
					int integerValue = reference.ElementId.IntegerValue;
					Duct duct = doc.GetElementById(reference.ElementId) as Duct;
					YJKPiping<Duct> hypiping = new YJKPiping<Duct>(doc.GetElement(reference) as Duct);
					bool flag = this.IsRiserDuct(hypiping.Piping);
					XYZ xyz = (hypiping.EndConnector.Origin - hypiping.StartConnector.Origin).Normalize();
					XYZ project = hypiping.GetProject(reference.GlobalPoint, true);
					bool flag2 = false;
					int num = this.JustInsertPointCanLayFan(fs, hypiping, project, ref flag2);
					if (num == 2)
					{
						YJKMessageBox.Information("选择风管太短无法放置风机！");
					}
					else
					{
						bool flag3 = false;
						Line line = (duct.Location as LocationCurve).Curve as Line;
						XYZ xyz2 = null;
						XYZ xyz3 = null;
						if (1 == (int)doc.ActiveView.ViewType && line != null && (fanParam.FamilyName == "轴流式管道风机" || fanParam.FamilyName == "离心式管道风机"))
						{
							using (LayFanJin layFanJin = new LayFanJin(new UIDocument(doc)))
							{
								layFanJin.StartPoint = project;
								layFanJin.ductCurve = line;
								new UIDocument(doc).Selection.PickPoint("请选择风机流向...");
								flag3 = layFanJin.rotate;
								xyz2 = layFanJin.verticalVectore;
								xyz3 = layFanJin.layPoint;
								layFanJin.Dispose();
							}
						}
						List<Duct> list;
						if (num == 3)
						{
							list = new List<Duct>();
							list.Add(hypiping.Piping);
						}
						else
						{
							list = hypiping.Separate(project);
						}
						new List<XYZ>().Add(project);
						FamilyInstanceCreationData item = new FamilyInstanceCreationData(project, fs, hypiping.Piping, 0);
						List<FamilyInstanceCreationData> list2 = new List<FamilyInstanceCreationData>();
						list2.Add(item);
						FamilyInstance familyInstance = doc.GetElement(doc.Create.NewFamilyInstances2(list2).ToList<ElementId>().FirstOrDefault<ElementId>()) as FamilyInstance;
						doc.Regenerate();
						double num2 = xyz.AngleTo(new XYZ(1.0, 0.0, 0.0));
						num2 = ((num2 > Math.PI*.5) ? (Math.PI - num2) : num2);
						Line line2;
						if (flag)
						{
							line2 = doc.CreatYJKLine(project, new XYZ(0.0, 1.0, 0.0), false);
						}
						else
						{
							line2 = doc.CreatYJKLine(project, new XYZ(0.0, 0.0, 1.0), false);
						}
						ElementTransformUtils.RotateElement(doc, familyInstance.Id, line2, -num2);
						doc.Regenerate();
						if (flag3 && xyz2 != null && xyz3 != null)
						{
							ElementTransformUtils.RotateElement(doc, familyInstance.Id, line2, Math.PI);
						}
						IList<Connector> hyelementConnector = connectHelper.GetYJKElementConnector(familyInstance, (Autodesk.Revit.DB.Domain)1);
						if (!xyz.IsAlmostEqualTo(hyelementConnector[0].CoordinateSystem.BasisZ, 0.0001) && !xyz.IsAlmostEqualTo(-hyelementConnector[0].CoordinateSystem.BasisZ, 0.0001))
						{
							num2 = Math.PI*2 - 2.0 * num2;
							ElementTransformUtils.RotateElement(doc, familyInstance.Id, line2, -num2);
						}
						if (fanParam.FamilyName == "轴流式管道风机" || fanParam.FamilyName == "离心式管道风机")
						{
							Parameter parameter = familyInstance.GetParameter("风机长度");
							if (parameter != null && !parameter.IsReadOnly)
							{
								parameter.Set(NumbericTools.mmToFeet(fanParam.Length));
							}
						}
						if (fanParam.FamilyName == "轴流式管道风机")
						{
							Parameter parameter2 = familyInstance.GetParameter("入口直径");
							if (parameter2 != null && !parameter2.IsReadOnly && fanParam.Diameter != 0.0)
							{
								parameter2.Set(NumbericTools.mmToFeet(fanParam.Diameter));
							}
						}
						if (!flag2)
						{
							if (fs.Family.Name.Contains("离心式"))
							{
								Parameter parameter3 = familyInstance.GetParameter("入口高度");
								Parameter parameter4 = familyInstance.GetParameter("入口宽度");
								if (parameter3 != null && !parameter3.IsReadOnly && parameter4 != null && !parameter4.IsReadOnly)
								{
									familyInstance.GetParameter("入口宽度").Set(hypiping.GetWeightOrDiameter());
									parameter3.Set(hypiping.GetHeightOrDiameter());
								}
							}
							else
							{
								Parameter parameter5 = familyInstance.GetParameter("入口直径");
								if (parameter5 != null && !parameter5.IsReadOnly && fanParam.FamilyName != "轴流式管道风机")
								{
									parameter5.Set(hypiping.GetWeightOrDiameter());
								}
							}
						}
						if (fanParam.FamilyName == "离心式管道风机" || fanParam.FamilyName == "轴流式管道风机")
						{
							Parameter parameter6 = familyInstance.GetParameter("风机长度");
							if (parameter6 != null && !parameter6.IsReadOnly && fanParam.Length != 0.0)
							{
								parameter6.Set(NumbericTools.mmToFeet(fanParam.Length));
							}
							if (flag2)
							{
								Parameter parameter7 = familyInstance.GetParameter("入口直径");
								if (parameter7 != null && !parameter7.IsReadOnly && fanParam.Diameter != 0.0)
								{
									parameter7.Set(NumbericTools.mmToFeet(fanParam.Diameter));
								}
								Parameter parameter8 = familyInstance.GetParameter("入口宽度");
								if (parameter8 != null && !parameter8.IsReadOnly && fanParam.Width != 0.0)
								{
									parameter8.Set(NumbericTools.mmToFeet(fanParam.Width));
								}
								Parameter parameter9 = familyInstance.GetParameter("入口高度");
								if (parameter9 != null && !parameter9.IsReadOnly && fanParam.Height != 0.0)
								{
									parameter9.Set(NumbericTools.mmToFeet(fanParam.Height));
								}
							}
						}
						else if (fanParam.FamilyName == "方形轴流风机")
						{
							Parameter parameter10 = familyInstance.GetParameter("风机长度");
							if (parameter10 != null && !parameter10.IsReadOnly && fanParam.Length != 0.0)
							{
								parameter10.Set(NumbericTools.mmToFeet(fanParam.Length));
							}
							Parameter parameter11 = familyInstance.GetParameter("风机宽度");
							if (parameter11 != null && !parameter11.IsReadOnly && fanParam.Width != 0.0)
							{
								parameter11.Set(NumbericTools.mmToFeet(fanParam.Width));
							}
						}
						else if (fanParam.FamilyName == "屋顶风机-离心式" || fanParam.FamilyName == "屋顶风机-轴流式")
						{
							Parameter parameter12 = familyInstance.GetParameter("风机直径");
							if (parameter12 != null && !parameter12.IsReadOnly && fanParam.Diameter != 0.0)
							{
								parameter12.Set(NumbericTools.mmToFeet(fanParam.Diameter));
							}
						}
						doc.Regenerate();
						if (hyelementConnector.First<Connector>().Shape != hypiping.Shape)
						{
							flag2 = true;
						}
						switch (num)
						{
						case 0:
							this.ConnectToDucts(hyelementConnector, list, doc, project, flag2, bLayFlex, fanParam, connectHelper, flag);
							break;
						case 1:
						{
							double num3 = list[0].get_Parameter(BuiltInParameter.CURVE_ELEM_LENGTH).AsDouble();
							double num4 = list[1].get_Parameter(BuiltInParameter.CURVE_ELEM_LENGTH).AsDouble();
							if (num3 > num4)
							{
								doc.DeleteElement(list[1]);
								list.RemoveAt(1);
							}
							else
							{
								doc.DeleteElement(list[0]);
								list.RemoveAt(0);
							}
							this.ConnectToDucts(hyelementConnector, list, doc, project, flag2, bLayFlex, fanParam, connectHelper, flag);
							break;
						}
						case 3:
							this.ConnectToDucts(hyelementConnector, list, doc, project, flag2, bLayFlex, fanParam, connectHelper, flag);
							break;
						}
						result = true;
					}
				}
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
				transaction.Commit();
				return result;
			}
			catch (Exception ex)
			{
				YJKMessageBox.Information(ex.Message);
				result = false;
			}
			finally
			{
				if (transaction != null && (int)transaction.GetStatus() != 3 && (int)transaction.GetStatus() != 2)
				{
					transaction.RollBack();
				}
			}
			return result;
		}

		private bool IsRiserDuct(Duct duct)
		{
			LocationCurve locationCurve = duct.Location as LocationCurve;
			double value = locationCurve.Curve.GetEndPoint(0).X - locationCurve.Curve.GetEndPoint(1).X;
			double value2 = locationCurve.Curve.GetEndPoint(0).Y - locationCurve.Curve.GetEndPoint(1).Y;
			return Math.Abs(value) < 0.0001 && Math.Abs(value2) < 0.0001;
		}

		private int JustInsertPointCanLayFan(FamilySymbol fs, YJKPiping<Duct> hyduct, XYZ ptSel, ref bool addTYDF)
		{
			int num = 0;
			string name = fs.Family.Name;
			double num2;
			if (name.Contains("轴流式"))
			{
				num2 = 300.0;
			}
			else
			{
				num2 = 250.0;
			}
			if ((name.Contains("轴流式") && hyduct.Shape == ConnectorSharp.Rect) || (name.Contains("离心式") && hyduct.Shape == ConnectorSharp.Round))
			{
				addTYDF = true;
				double num3 = (hyduct.GetWeightOrDiameter() > hyduct.GetHeightOrDiameter()) ? hyduct.GetWeightOrDiameter() : hyduct.GetHeightOrDiameter();
				if (num3 < 0.82020997375328086)
				{
					num2 += 200.0;
				}
				else if (num3 < 2.0669291338582676)
				{
					num2 += 350.0;
				}
				else if (num3 < 5.2493438320209975)
				{
					num2 += 500.0;
				}
				else
				{
					num2 += 700.0;
				}
			}
			XYZ origin = hyduct.StartConnector.Origin;
			XYZ origin2 = hyduct.EndConnector.Origin;
			if (ptSel.DistanceTo(origin) < num2 / 304.8)
			{
				num++;
			}
			if (ptSel.DistanceTo(origin2) < num2 / 304.8)
			{
				num++;
			}
			if (ptSel.IsAlmostEqualTo(origin, 0.0001) || ptSel.IsAlmostEqualTo(origin2, 0.0001))
			{
				num = 3;
			}
			return num;
		}

		private void ConnectToDucts(IList<Connector> conns, List<Duct> ducts, Autodesk.Revit.DB.Document doc, XYZ ptInsert, bool addTYDF, bool bLayFlex, EquipmentFanParam2 fanParam, ConnectHelper cm, bool bIsRiserDuct)
		{
			FamilySymbol familySymbol = null;
			FamilySymbol fd = null;
			new Dictionary<Connector, Connector>();
			FamilyInstance familyInstance = conns[0].Owner as FamilyInstance;
			if (addTYDF)
			{
				familySymbol = this.GetDuctFittingFamilySymbolByFamilyName("天圆地方", doc);
				foreach (object obj in cm.LayFamilyInstance(new List<XYZ>
				{
					new XYZ(0.0, 0.0, 0.0)
				}, familySymbol, doc.ActiveView.GenLevel, 0, doc))
				{
					Element element = (Element)obj;
					doc.Delete(element.Id);
				}
			}
			if (bLayFlex)
			{
				fd = this.setFlexParameter(doc, fanParam, conns[0]);
			}
			foreach (Connector connector in conns)
			{
				foreach (Duct piping in ducts)
				{
					YJKPiping<Duct> hypiping = new YJKPiping<Duct>(piping);
					Connector closeConnector = hypiping.GetCloseConnector(ptInsert, false);
					doc.Regenerate();
					if (this.CompareTwoConnectorDir(connector, closeConnector))
					{
						if (bLayFlex)
						{
							this.LayFlex(bIsRiserDuct, connector, doc, cm, fd, familyInstance, hypiping, addTYDF, familySymbol, ptInsert, closeConnector, fanParam);
						}
						else
						{
							if (addTYDF)
							{
								hypiping.ChangeFirstTYDF(familySymbol);
							}
							closeConnector.ConnectTo(connector);
							doc.Create.NewTransitionFitting(closeConnector, connector);
						}
					}
				}
			}
			ElementTransformUtils.MoveElement(doc, familyInstance.Id, new XYZ(0.01, 0.0, 0.0));
			ElementTransformUtils.MoveElement(doc, familyInstance.Id, new XYZ(-0.01, 0.0, 0.0));
			doc.Regenerate();
		}

		private FamilySymbol setFlexParameter(Autodesk.Revit.DB.Document doc, EquipmentFanParam2 fanParam, Connector conn)
		{
			new SpaceFamilyDataReader();
			string familyName = "";
			string symbolName = "";
			if (fanParam.FamilyName == "离心式管道风机" || YJKRevitTools.GetConnectorSharpName(conn) == "矩形")
			{
				familyName = "矩形软连接";
				symbolName = "标准";
			}
			else if (fanParam.FamilyName == "轴流式管道风机" || YJKRevitTools.GetConnectorSharpName(conn) == "圆形")
			{
				familyName = "圆形软连接";
				symbolName = "标准";
			}
			return this.GetDuctFittingFamilySymbolByFamilyNameAndSymbol(familyName, symbolName, doc);
		}

		private FamilySymbol GetDuctFittingFamilySymbolByFamilyNameAndSymbol(string FamilyName, string SymbolName, Autodesk.Revit.DB.Document doc)
		{
			FamilySymbol familySymbol = null;
			foreach (Element element in YJKElementFilter.GetElementsOfType(doc, typeof(FamilySymbol), BuiltInCategory.OST_DuctAccessory))
			{
				if ((element as FamilySymbol).Family.Name.Contains(FamilyName))
				{
					familySymbol = (element as FamilySymbol);
				}
			}
			if (familySymbol == null)
			{
				SubTransaction subTransaction = null;
				try
				{
					string text = Path.Combine(Product.FamilyLocation, RevitVersion.GetVersionNumber(doc), "fitting", FamilyName + ".rfa");
					subTransaction = new SubTransaction(doc);
					subTransaction.Start();
					FamilySymbol familySymbol2;
					doc.LoadFamilySymbol(text, SymbolName, ref familySymbol2);
					familySymbol = familySymbol2;
					subTransaction.Commit();
				}
				catch (Exception ex)
				{
					ex.ToString();
				}
				finally
				{
					if (subTransaction != null && (int)subTransaction.GetStatus() != 3)
					{
						subTransaction.RollBack();
					}
				}
			}
			return familySymbol;
		}

		private void LayFlex(bool bIsRiserDuct, Connector conn, Autodesk.Revit.DB.Document doc, ConnectHelper cm, FamilySymbol fd, FamilyInstance fi, YJKPiping<Duct> hyduct, bool addTYDF, FamilySymbol fs, XYZ ptInsert, Connector ductconn, EquipmentFanParam2 fanParam)
		{
			try
			{
				Line line = null;
				if (bIsRiserDuct)
				{
					line = doc.CreatYJKLine(conn.Origin, new XYZ(0.0, 1.0, 0.0), false);
				}
				else
				{
					line = doc.CreatYJKLine(conn.Origin, new XYZ(0.0, 0.0, 1.0), false);
				}
				new List<XYZ>().Add(conn.Origin);
				FamilyInstanceCreationData item = new FamilyInstanceCreationData(conn.Origin, fd, conn.Owner, 0);
				List<FamilyInstanceCreationData> list = new List<FamilyInstanceCreationData>();
				list.Add(item);
				FamilyInstance familyInstance = doc.GetElement(doc.Create.NewFamilyInstances2(list).ToList<ElementId>().FirstOrDefault<ElementId>()) as FamilyInstance;
				doc.Regenerate();
				foreach (Connector flexConn in YJKRevitTools.GetElementAllConnector(familyInstance))
				{
					this.SetFlexFittingSize(flexConn, conn);
				}
				doc.Regenerate();
				Parameter parameter = familyInstance.GetParameter("软连接长度");
				if (parameter != null && !parameter.IsReadOnly)
				{
					familyInstance.GetParameter("软连接长度").Set(NumbericTools.mmToFeet(fanParam.FlexLength));
				}
				XYZ xyz = (hyduct.EndConnector.Origin - hyduct.StartConnector.Origin).Normalize();
				double num = xyz.AngleTo(new XYZ(1.0, 0.0, 0.0));
				ElementTransformUtils.RotateElement(doc, familyInstance.Id, line, -num);
				IList<Connector> hyelementConnector = cm.GetYJKElementConnector(familyInstance, (Autodesk.Revit.DB.Domain)1);
				if (!xyz.IsAlmostEqualTo(hyelementConnector[0].CoordinateSystem.BasisZ, 0.0001) && !xyz.IsAlmostEqualTo(-hyelementConnector[0].CoordinateSystem.BasisZ, 0.0001))
				{
					num = Math.PI*2 - 2.0 * num;
					ElementTransformUtils.RotateElement(doc, familyInstance.Id, line, -num);
				}
				if (addTYDF)
				{
					hyduct.ChangeFirstTYDF(fs);
					hyelementConnector.GetNearestConnector(ptInsert).ConnectTo(conn);
					hyelementConnector.GetFarestConnector(ptInsert).ConnectTo(ductconn);
					doc.Create.NewTransitionFitting(ductconn, hyelementConnector.GetFarestConnector(ptInsert));
				}
				else
				{
					hyelementConnector.GetNearestConnector(ptInsert).ConnectTo(conn);
					Connector farestConnector = hyelementConnector.GetFarestConnector(ptInsert);
					if (YJKRevitTools.GetConnectorSharpName(farestConnector) == "圆形" && YJKRevitTools.GetConnectorSharpName(ductconn) == "圆形" && Math.Abs(farestConnector.Radius - ductconn.Radius) > 0.0016404199475065617)
					{
						YJKRotateFamilyInstance hyrotateFamilyInstance = new YJKRotateFamilyInstance();
						Duct duct = ductconn.Owner as Duct;
						new YJKPiping<Duct>(duct);
						hyduct.GetCloseConnector(farestConnector.Origin, true);
						Duct duct2 = YJKRevitTools.NewDuct(duct, farestConnector.Origin, farestConnector.Origin.Add(farestConnector.CoordinateSystem.BasisZ * 150.0 / 304.8));
						YJKPiping<Duct> hypiping = new YJKPiping<Duct>(duct2);
						doc.Regenerate();
						this.SetDuctByConn(ref duct2, farestConnector);
						ductconn = hyduct.GetCloseConnector(farestConnector.Origin, false);
						Connector connector = hypiping.GetCloseConnector(farestConnector.Origin, true);
						FamilyInstance fi2 = doc.Create.NewTransitionFitting(connector, ductconn);
						doc.DeleteElement(duct2);
						hyrotateFamilyInstance.MoveFamilyInstance(fi2, ductconn.CoordinateSystem.BasisX * 5.0 / 304.8);
						doc.Regenerate();
						connector = this.GetNotConnectedConn(fi2);
						connector.ConnectTo(farestConnector);
						hyrotateFamilyInstance.MoveFamilyInstance(fi2, ductconn.CoordinateSystem.BasisX * 5.0 / 304.8);
					}
					else
					{
						farestConnector.ConnectTo(ductconn);
					}
				}
				doc.Regenerate();
			}
			catch (Exception)
			{
				throw new Exception("软连接长度过小或者风管尺寸过小，请调整软连接长度或风管！");
			}
		}

		private Connector GetNotConnectedConn(FamilyInstance fi)
		{
			Connector result = null;
			if (fi != null)
			{
				ConnectorSetIterator connectorSetIterator = fi.MEPModel.ConnectorManager.Connectors.ForwardIterator();
				while (connectorSetIterator.MoveNext())
				{
					object obj = connectorSetIterator.Current;
					Connector connector = obj as Connector;
					if (connector != null && !connector.IsConnected)
					{
						result = connector;
					}
				}
			}
			return result;
		}

		private bool SetDuctByConn(ref Duct duct, Connector conn)
		{
			foreach (object obj in duct.ConnectorManager.Connectors)
			{
				Connector connector = (Connector)obj;
				if (connector.Shape != conn.Shape)
				{
					return false;
				}
				if (conn.Shape == ConnectorSharp.Round)
				{
					connector.Radius = conn.Radius;
				}
				else if (conn.Shape == ConnectorSharp.Rect || conn.Shape == ConnectorSharp.Oval)
				{
					connector.Width = conn.Width;
					connector.Height = conn.Height;
				}
			}
			return true;
		}

		private void SetFlexFittingSize(Connector flexConn, Connector fanConn)
		{
			string connectorSharpName = YJKRevitTools.GetConnectorSharpName(flexConn);
			string connectorSharpName2 = YJKRevitTools.GetConnectorSharpName(fanConn);
			if (connectorSharpName != connectorSharpName2)
			{
				return;
			}
			if (connectorSharpName == "圆形")
			{
				flexConn.Radius = fanConn.Radius;
				return;
			}
			flexConn.Width = fanConn.Width;
			flexConn.Height = fanConn.Height;
		}

		public XYZ GetXYZByStartXYZDistance(XYZ startXYZ, XYZ endXYZ, double distance)
		{
			XYZ xyz = (endXYZ - startXYZ).Normalize();
			return startXYZ + distance * xyz;
		}

		private bool CompareTwoConnectorDir(Connector conn1, Connector conn2)
		{
			bool result = false;
			XYZ basisZ = conn1.CoordinateSystem.BasisZ;
			XYZ basisZ2 = conn2.CoordinateSystem.BasisZ;
			double num = basisZ.AngleTo(basisZ2);
			if (Math.Abs(num - Math.PI*.5) < 0.001)
			{
				XYZ point = ((conn1.Owner as FamilyInstance).Location as LocationPoint).Point;
				if (conn1.Origin.DistanceTo(conn2.Origin) < conn2.Origin.DistanceTo(point))
				{
					result = true;
				}
			}
			else if (Math.Abs(num - Math.PI) < 0.001)
			{
				result = true;
			}
			return result;
		}

		private FamilySymbol GetDuctFittingFamilySymbolByFamilyName(string FamilyName, Autodesk.Revit.DB.Document doc)
		{
			FamilySymbol familySymbol = null;
			foreach (Element element in YJKElementFilter.GetElementsOfType(doc, typeof(FamilySymbol), BuiltInCategory.OST_DuctFitting))
			{
				if ((element as FamilySymbol).Family.Name.Contains(FamilyName))
				{
					familySymbol = (element as FamilySymbol);
				}
			}
			if (familySymbol == null)
			{
				Family family = null;
				SubTransaction subTransaction = null;
				try
				{
					string text = Path.Combine(Product.FamilyLocation, RevitVersion.GetVersionNumber(doc), "Fitting", FamilyName + ".rfa");
					subTransaction = new SubTransaction(doc);
					subTransaction.Start();
					doc.LoadFamily(text, out family);
					subTransaction.Commit();
				}
				catch (Exception ex)
				{
					ex.ToString();
				}
				finally
				{
					if (subTransaction != null && (int)subTransaction.GetStatus() != 3)
					{
						subTransaction.RollBack();
					}
				}
				if (family != null)
				{
					using (List<FamilySymbol>.Enumerator enumerator2 = family.GetSymbols().GetEnumerator())
					{
						if (enumerator2.MoveNext())
						{
							familySymbol = enumerator2.Current;
						}
					}
				}
			}
			return familySymbol;
		}
	}
}
